import { useEventListener } from '@vueuse/core'

export default function (el: Ref<HTMLElement | null | undefined>) {
	const x = ref(0)
	const y = ref(0)
	const startPosition = { x: 0, y: 0 }
	const endPosition = { x: 0, y: 0 }
	let removeMousemove: Function
	let removeMouseup: Function
	let removeMousout: Function

	function setEndPosition() {
		endPosition.x = x.value
		endPosition.y = y.value
	}

	const removeMousedown = useEventListener(el, 'mousedown', (event: MouseEvent) => {
		const { clientX, clientY } = event
		startPosition.x = clientX
		startPosition.y = clientY
		el.value!.classList.add('dragging')

		removeMousemove = useEventListener(document, 'mousemove', (event: MouseEvent) => {
			const { clientX, clientY } = event
			x.value = clientX - startPosition.x + endPosition.x
			y.value = clientY - startPosition.y + endPosition.y
		})

		removeMouseup = useEventListener(document, 'mouseup', () => {
			setEndPosition()
			removeMousemove && removeMousemove()
			removeMouseup && removeMouseup()
			removeMousout && removeMousout()
			el.value!.classList.remove('dragging')
		})

		removeMousout = useEventListener(document, 'mouseout', () => {
			setEndPosition()
			removeMousout && removeMousout()
			removeMousemove && removeMousemove()
		})
	})

	watch([x, y], ([xValue, yValue]) => {
		el.value!.style.transform = `translate(${xValue}px, ${yValue}px)`
	})

	function resetDrag() {
		x.value = 0
		y.value = 0
		endPosition.x = 0
		endPosition.y = 0
	}

	function removeDragListener() {
		removeMousedown && removeMousedown()
		removeMousemove && removeMousemove()
		removeMouseup && removeMouseup()
		removeMousout && removeMousout()
	}

	onUnmounted(() => {
		resetDrag()
		removeDragListener()
	})

	return { x, y, resetDrag, removeDragListener }
}
